
//http://www.java-samples.com/showtutorial.php?tutorialid=152

package microarray;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.io.*;


import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import com.google.appengine.api.datastore.Key;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable
public class ESummary extends EUtil implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 5111562096219644750L;
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;
	
	HashMap<String, Summary> summaries;
	public HashMap<String, Summary> getSummaries() {
		return summaries;
	}
	private String textValue;
	
	//to maintain context
	private Summary summary;
	
	private String sampleKey;
	private String nameAtt;
	private String typeAtt;
	
    public ESummary(String queryKey, String webEnv) throws Exception {
    	summaries = new HashMap<String, Summary>();
    	
    	Map<String, String> params = new TreeMap<String, String>();
    	
    	params.put("WebEnv", webEnv);
    	params.put("query_key", queryKey);
    	
    	String baseURL = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?";
    	InputStream bin = openInput(baseURL, params);
    	parseData(bin);
    }
    

	public void parseData(InputStream in) throws Exception {

		//get a factory
		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {

			//get a new instance of parser
			SAXParser sp = spf.newSAXParser();

			//parse the file and also register this class for call backs
			sp.parse(in, this);

		}catch(SAXException se) {
			se.printStackTrace();
		}catch(ParserConfigurationException pce) {
			pce.printStackTrace();
		}catch (IOException ie) {
			ie.printStackTrace();
		}
	}
	
	//Event Handlers
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		//reset
		textValue = "";
		nameAtt = "";
		typeAtt = "";
		if (qName.equalsIgnoreCase("Item")) {
			nameAtt = attributes.getValue("Name");
			typeAtt = attributes.getValue("Type");
			@SuppressWarnings("unused")
			int i = 0;
		}
		else if(qName.equalsIgnoreCase("DocSum")) {
			summary = new Summary();
		}
	}
	

	public void characters(char[] ch, int start, int length) throws SAXException {
		textValue = new String(ch,start,length);
	}
	
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if(qName.equalsIgnoreCase("DocSum")) {
			//add it to the list
			summaries.put(summary.getId(),summary);	
		}else if (qName.equalsIgnoreCase("Item") && (typeAtt.equalsIgnoreCase("String") ||typeAtt.equalsIgnoreCase("date"))) {
			if (!nameAtt.equals("")){
				//
				if (nameAtt.equals("Accession"))
				{
					sampleKey = textValue;
				}
				else if (nameAtt.equals("Title"))
				{
					if (sampleKey != null){
						summary.addSample(sampleKey,textValue);
						sampleKey = null;
					}
				}
				else if (nameAtt.equalsIgnoreCase("Author") || nameAtt.equalsIgnoreCase("LastAuthor"))
				{
					summary.addAuthor(textValue);
				}
				else
				{
					summary.addItem(nameAtt.toLowerCase(), textValue);
				}
			}
		}
		else if (qName.equals("Id"))
		{
			summary.setId(textValue);
		}
	}
	
	public String toString()
	{
		String out = "";
		for (Summary summary : summaries.values())
			out += summary.toString() +  "\n";
		return out;
	}
	
	public Summary getSummary(String id)
	{
		return summaries.get(id);
	}
	
    public String getValue(String id, String field)
    {
    	if (summaries.containsKey(id))
    		return summaries.get(id).getItem(field);
    	else 
    		return id + " not found";
    }


	public void setKey(Key key) {
		this.key = key;
	}


	public Key getKey() {
		return key;
	} 
    
}



	
	


